Skip to content

修复委派任务的权限策略继承#29

Closed
Lixtt wants to merge 1 commit into
AI45Lab:mainfrom
Lixtt:fix/task-agent-permissions
Closed

修复委派任务的权限策略继承#29
Lixtt wants to merge 1 commit into
AI45Lab:mainfrom
Lixtt:fix/task-agent-permissions

Conversation

@Lixtt
Copy link
Copy Markdown
Contributor

@Lixtt Lixtt commented May 13, 2026

修复 #28

变更内容

  • task / parallel_task 创建子运行时,将被委派 agent 的非默认权限策略写入子 AgentConfig.permission_checker
  • 将正常 agent binding 路径里的权限判断改为识别完整的非默认 PermissionPolicy,覆盖 default_decision = Allow 这类没有 allow/deny 列表但仍然显式配置的策略。
  • 增加单元测试,覆盖 allow-list 权限和 default-allow 权限在委派子运行中的继承行为。

验证

  • cargo fmt
  • cargo test -p a3s-code-core --lib
  • cargo test -p a3s-code-core --lib tools::task::tests
  • cargo test -p a3s-code-core --lib agent_api::agent_binding::tests

补充说明:不带 --libcargo test -p a3s-code-core <filter> 会编译 integration tests,目前 main 上已有的 core/tests/test_web_search_headless.rs 存在 Option<SearchConfig>Option<Arc<SearchConfig>> 类型不匹配问题,会阻断该命令;这个问题不是本 PR 引入的。

@Lixtt Lixtt closed this May 13, 2026
@Lixtt Lixtt changed the title Fix delegated task permission propagation 修复委派任务的权限策略继承 May 13, 2026
@Lixtt Lixtt reopened this May 13, 2026
@ZhiXiao-Lin
Copy link
Copy Markdown
Contributor

Thanks for the PR! The issue you identified is correct, and we appreciate the fix.

However, we've already addressed this in v2.5.0 (currently being released) with a broader architectural refactoring that goes beyond the immediate permission inheritance fix. Your PR is now superseded by the v2.5.0 changes.

How v2.5.0 solves this

What your PR does (and we agree with)

  • Propagate permission_checker into child AgentConfig
  • Cover the default_decision = Allow edge case via is_default_policy()

What v2.5.0 does additionally

  1. Unified AgentDefinition::apply_to(&mut AgentConfig) — a single method that maps all agent definition fields onto child config. This eliminates the root cause: two independent code paths that can drift out of sync.

  2. ConfirmationInheritance enum — explicitly controls how child runs resolve Ask decisions:

    • AutoApprove (default for agents with permissions): auto-approve Ask decisions
    • DenyOnAsk: strict mode
    • InheritParent: inherit parent's confirmation manager

    This means even if permission_checker returns Ask for an uncovered tool, the child run won't hit MissingConfirmationManager — it will auto-approve by default.

  3. Removed guard_policy — the redundant defense-in-depth layer on ToolExecutor that you kept in your PR. Since apply_to() always sets permission_checker, the safety gate handles everything.

  4. ChildRunContext — explicit parent-to-child capability inheritance (security provider, hooks, skills, timeouts).

  5. Mock LLM contract tests — 5 tests that verify the full task delegation path without network, covering permission allow/deny, confirmation auto-approve, step budget, and parallel execution.

  6. SDK alignmentconfirmation_inheritance field exposed in both Node and Python SDKs.

The is_default_policy() edge case

Your PR correctly identifies that default_decision = Allow (without explicit allow/deny rules) should also be propagated. In v2.5.0, this edge case is handled differently: ConfirmationInheritance::AutoApprove ensures that even if permission_checker is not set (because the policy looks "default"), the child run won't be denied. The net effect is the same — tools execute successfully.

The test_web_search_headless.rs issue you noted

We've also fixed this in v2.5.0 (commit 71ec109): wrapped SearchConfig in Arc to match the updated ToolContext field type.


Closing this PR since v2.5.0 fully supersedes it. Thank you for the contribution and the detailed analysis in Issue #28 — it directly informed our architectural improvements!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants